package com.sangeng.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sangeng.constants.SystemConstants;
import com.sangeng.domain.ResponseResult;
import com.sangeng.domain.dto.RoleAddDto;
import com.sangeng.domain.dto.RoleDto;
import com.sangeng.domain.dto.RoleUpdateDto;
import com.sangeng.domain.entity.Role;
import com.sangeng.domain.entity.RoleMenu;
import com.sangeng.domain.vo.PageVo;
import com.sangeng.domain.vo.RoleListVo;
import com.sangeng.domain.vo.RoleUpdateVo;
import com.sangeng.mapper.RoleMapper;
import com.sangeng.service.RoleMenuService;
import com.sangeng.service.RoleService;
import com.sangeng.utils.BeanCopyUtils;
import com.sangeng.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色信息表(Role)表服务实现类
 *
 * @author makejava
 * @since 2023-10-09 20:38:08
 */
@Service("roleService")
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
    @Autowired
    private RoleMenuService roleMenuService;
    @Autowired
    private RoleMapper roleMapper;
    /**
     * 根据用户id查询用户角色列表
     * @param id
     * @return
     */

    @Override
    public List<String> selectRoleKeyByUserId(Long id) {
        //如果是管理员，角色列表只有admin
        if(SecurityUtils.isAdmin()){
            //是管理员
            List<String> roleList=new ArrayList<>();
            roleList.add("admin");
            return roleList;
        }
        //否则，根据用户id查询角色列表
        return roleMapper.selectRoleKeyByUserId(id);
    }
    /**
     * 查询角色列表
     * 需要有角色列表分页查询的功能。要求能够针对角色名称进行模糊查询。
     * 要求能够针对状态进行查询。要求按照role_sort进行升序排列。
     * @param pageNum
     * @param pageSize
     * @param roleName
     * @param status
     * @return
     */
    @Override
    public ResponseResult<PageVo> listAll(Integer pageNum, Integer pageSize,
                                          String roleName, Character status) {
        //封装条件
        LambdaQueryWrapper<Role> lqw=new LambdaQueryWrapper<>();
        lqw.eq(status!=null,Role::getStatus,status);
        lqw.like(roleName!=null,Role::getRoleName,roleName);
        lqw.orderByAsc(Role::getRoleSort);
        Page<Role> page=new Page<>(pageNum,pageSize);
        page(page,lqw);
        //数据转换
        List<RoleListVo> roleListVos = BeanCopyUtils.copyBeanList(page.getRecords(), RoleListVo.class);
        return ResponseResult.okResult(new PageVo(roleListVos,page.getTotal()));
    }
    /**
     * 修改角色的状态
     * @param roleUpdateDto
     * @return
     */
    @Override
    public ResponseResult changeRoleStatus(RoleUpdateDto roleUpdateDto) {
        //数据类型转换
        Role role=new Role();
        role.setId(roleUpdateDto.getRoleId());
        role.setStatus(String.valueOf(roleUpdateDto.getStatus()));
        updateById(role);
        return ResponseResult.okResult();
    }
    /**
     * 需要提供新增角色的功能。新增角色时能够直接设置角色所关联的菜单权限。
     * @param roleAddDto
     * @return
     */
    @Override
    @Transactional
    public ResponseResult saveRole(RoleAddDto roleAddDto) {
        //添加角色
        Role role = BeanCopyUtils.copyBean(roleAddDto, Role.class);
        save(role);
        //获取菜单id列表
        List<Long> menuIds = roleAddDto.getMenuIds();
        //数据封装
        List<RoleMenu> roleMenuList = menuIds.stream().
                map(menuId -> new RoleMenu(role.getId(), menuId))
                .collect(Collectors.toList());
        //批量插入角色权限表中
        roleMenuService.saveBatch(roleMenuList);
        return ResponseResult.okResult();
    }
    /**
     * 根据角色id查询角色详情
     * @param id
     * @return
     */
    @Override
    public ResponseResult<RoleUpdateVo> getDataById(Long id) {
        Role role = getById(id);
        RoleUpdateVo roleUpdateVo = BeanCopyUtils.copyBean(role, RoleUpdateVo.class);
        return ResponseResult.okResult(roleUpdateVo);
    }
    /**
     * 更新用户信息
     * @param roleDto
     * @return
     */
    @Override
    @Transactional
    public ResponseResult updateData(RoleDto roleDto) {
        //先更新角色表
        Role role = BeanCopyUtils.copyBean(roleDto, Role.class);
        updateById(role);
        //再更新角色权限表
        //先删除该角色所对应的权限记录
        LambdaQueryWrapper<RoleMenu> lqw=new LambdaQueryWrapper<>();
        lqw.eq(RoleMenu::getRoleId,role.getId());
        roleMenuService.remove(lqw);
        //再添加修改的权限记录
        List<Long> menuIds = roleDto.getMenuIds();
        List<RoleMenu> roleMenuList = menuIds.stream()
                .map(menuId -> new RoleMenu(role.getId(), menuId))
                .collect(Collectors.toList());
        roleMenuService.saveBatch(roleMenuList);
        return ResponseResult.okResult();
    }
    /**
     * 根据角色id删除数据
     * @param id
     * @return
     */
    @Override
    public ResponseResult deleteDataById(Long id) {
        //删除对应的角色
        removeById(id);
        //再角色权限表中删除相应的权限记录
        LambdaQueryWrapper<RoleMenu> lqw=new LambdaQueryWrapper<>();
        lqw.eq(RoleMenu::getRoleId,id);
        roleMenuService.remove(lqw);
        return ResponseResult.okResult();
    }
    /**
     * 获取所有状态正常的角色列表
     * @return
     */

    @Override
    public ResponseResult<List<Role>> getAllRole() {
        LambdaQueryWrapper<Role> lqw=new LambdaQueryWrapper<>();
        lqw.eq(Role::getStatus, SystemConstants.ROLE_STATUS_NORMAL);
        List<Role> roleList = list(lqw);
        return ResponseResult.okResult(roleList);
    }


}
